'''
Created on Apr 3, 2012

@author: Johnathon
'''
from LineValues import X
import util

def simulate(inputVector, primaryInputs, primaryOutputs, lines, gates, dFront=None):
    #Check to see that we have a input value for each of the primary inputs
    if len(inputVector) != len(primaryInputs):
        print util.printListOfLineValues(inputVector)
        print len(primaryInputs)
        print len(inputVector)
        raise Exception("Input vector does not match up with number of primary inputs")
    
    #Clear any remaining state in the circuit
    for lineList in lines:
        for line in lineList:
                line.value = X

    #Apply the primary inputs
    for i in range(len(inputVector)):
        primaryInputs[i].driveValue(inputVector[i])
    #Simulate the logic through each level of gates
    if dFront is None:
        for level in gates:
            for gate in level:
                gate.evaluate()
    else:
        for level in gates:
            for gate in level:
                gate.evaluate()
                gate.addToDFrontier(dFront)

    output = list()
    gateState = list()
    
    #Gather the values on the primary output lines
    for po in primaryOutputs:
        output.append(po.value)
    #Gather the output value of each gate
    for level in gates:
        for gate in level:
            gateState.append( (gate.output.value, gate.inputs) )
    
    l = [i.value for level in lines for i in level]
            
    r = dict()
    r['output'] = output
    r['state'] = gateState
    r['lines'] = l
    return r









